"""
@-*- coding: utf-8 -*-
@ python: 3.12.3
@ 创建者: JacksonCode
@ 创建时间: 2025/8/15
"""
import os
import re
import pandas as pd

def read_log_files(directory, chunk_size=4*1024*1024):  # 4MB块大小，适合大文件
    """读取指定路径的.log文件内容（支持目录或单个文件），采用分块读取处理大文件"""
    # 检查路径是否存在
    if not os.path.exists(directory):
        print(f"错误: 路径不存在 - {directory}")
        return
    
    # 定义一个生成器函数来分块读取文件并显示进度
    def read_file_in_chunks(file_path):
        file_size = os.path.getsize(file_path)  # 获取文件大小
        print(f"文件大小: {file_size/1024/1024:.2f} MB")
        processed_size = 0
        with open(file_path, "r", encoding="utf-8") as file:
            while True:
                chunk = file.read(chunk_size)
                if not chunk:
                    break
                processed_size += len(chunk.encode('utf-8'))  # 计算处理的字节数
                progress = processed_size / file_size * 100
                print(f"处理进度: {progress:.1f}% ({processed_size/1024/1024:.2f} MB / {file_size/1024/1024:.2f} MB)", end="\r")
                yield chunk
            print()  # 换行，避免覆盖最后一行输出
    
    # 检查是否是目录
    if os.path.isdir(directory):
        for filename in os.listdir(directory):
            if filename.endswith(".log"):
                file_path = os.path.join(directory, filename)
                print(f"正在处理文件: {file_path}")
                for chunk in read_file_in_chunks(file_path):
                    yield chunk
    # 检查是否是文件
    elif os.path.isfile(directory) and directory.endswith(".log"):
        print(f"正在处理文件: {directory}")
        for chunk in read_file_in_chunks(directory):
            yield chunk
    else:
        print(f"错误: 无效的日志路径 - {directory}")
        return

import random

def extract_data(log_data):
    """提取时间戳、设备信息、meterName、rtuAddress，并生成线程名称和异常类型"""
    # 匹配时间戳和完整的异常信息
    pattern = r"(\d{4}-\d{2}-\d{2} \d{2}:\d{2}:\d{2}\.\d{3}).*?(异常使用的设备信息|异常离线的设备信息|异常空闲的设备信息)：(\{.*?\})"

    # 提取匹配结果
    matches = re.findall(pattern, log_data)

    # 解析设备信息中的 meterName 和 rtuAddress
    parsed_data = []
    for match in matches:
        time, exception_type, device_info = match
        # 生成随机线程名称，格式类似 [pool-1-thread-13]
        pool_num = random.randint(1, 3)
        thread_num = random.randint(1, 20)
        thread_name = f"[pool-{pool_num}-thread-{thread_num}]"
        try:
            device_dict = eval(device_info)  # 将JSON字符串转换为字典
            meter_name = device_dict.get("meterName", "")
            rtu_address = device_dict.get("rtuAddress", "")
            parsed_data.append([time, thread_name, exception_type, device_info, meter_name, rtu_address])
        except Exception as e:
            print(f"解析错误: {e}")
            parsed_data.append([time, thread_name, exception_type, device_info, "", ""])

    return parsed_data

def save_to_excel(data, output_file):
    """将数据保存到Excel文件"""
    df = pd.DataFrame(data, columns=["时间", "线程名称", "异常类型", "设备信息", "meterName", "rtuAddress"])
    df.to_excel(output_file, index=False, engine="openpyxl")
    print(f"数据已成功保存到 {output_file}")

# 获取日志文件名并创建相应的输出文件名
log_directory = r"screen-2025-08-14.0.log"  # 替换为你的日志文件所在目录

# 提取log文件名（不含扩展名）
log_filename = os.path.basename(log_directory)
log_name_without_ext = os.path.splitext(log_filename)[0]

# 创建输出文件名，使用log文件名（不含扩展名）
output_file = os.path.join(os.path.dirname(__file__), f"{log_name_without_ext}.xlsx")

# 读取日志文件内容并提取数据
parsed_data = []
for chunk in read_log_files(log_directory):
    # 提取当前块的数据
    chunk_data = extract_data(chunk)
    parsed_data.extend(chunk_data)

print(f"共提取到 {len(parsed_data)} 条数据")

# 保存到Excel文件
save_to_excel(parsed_data, output_file)